package com.djhu.hadoop.fileservice;
/**
 * Created by zw on 2017/12/14.
 */

import com.djhu.hadoop.BasicFileInfo;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;

/**
 * code is far away from bug with the animal protecting
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 *
 * <p>
 * ---------------------------------
 */
public class HdfsFileService implements FileService{
//    private FileNameGenerator fileNameGenerator;

    //private Map<String,String> fileCache;

    //private Integer cacheSize = 10;
    private FileSystem fileSystem;

    @Override
    public BasicFileInfo upload(File file, String remote) {
        return null;
    }

    @Override
    public BasicFileInfo upload(byte[] bytes, String remotefile) {
        Path path = new Path(remotefile);
        BasicFileInfo basicFileInfo = new BasicFileInfo();
        basicFileInfo.setRemoteFile(remotefile);
        basicFileInfo.setLocalFile("string");
        boolean isExist = false;
        FSDataOutputStream fsDataOutputStream = null;
        try {
            isExist = fileSystem.exists(path);
            //byte[] bytes = string.getBytes("UTF-8");
            if (isExist){
                FileStatus fileStatus = fileSystem.getFileStatus(path);
                basicFileInfo.setStart(fileStatus.getLen());
                basicFileInfo.setLength(bytes.length);
                fsDataOutputStream = fileSystem.append(path);
                fsDataOutputStream.write(bytes);
                fsDataOutputStream.flush();
            }else {
                fsDataOutputStream = fileSystem.create(path);
                fsDataOutputStream.write(bytes);
                basicFileInfo.setStart(0);
                basicFileInfo.setLength(bytes.length);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            if (fsDataOutputStream != null){
                try {
                    fsDataOutputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return basicFileInfo;
    }


    @Override
    public byte[] readBytes(BasicFileInfo basicFileInfo) {
        FSDataInputStream fsDataInputStream = null;
        RandomAccessFile fileWriter = null;
        try {
            fsDataInputStream = fileSystem.open(new Path(basicFileInfo.getRemoteFile()));
            fsDataInputStream.seek(basicFileInfo.getStart());
            byte[] bytes = new byte[(int) basicFileInfo.getLength()];
            fsDataInputStream.readFully(bytes);
            return bytes;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                if (fsDataInputStream != null){
                    fsDataInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fileWriter !=null){
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



    @Override
    public BasicFileInfo upload(String string, String remotefile)  {
        try {
            return upload(string.getBytes("UTF-8"),remotefile);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }


    public BasicFileInfo doanload( BasicFileInfo basicFileInfo){
        RandomAccessFile fileWriter = null;
        try {
            byte[] bytes = readBytes(basicFileInfo);
            fileWriter = new RandomAccessFile(basicFileInfo.getLocalFile(),"rw");
            fileWriter.write(bytes);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                if (fileWriter !=null){
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return basicFileInfo;
    }

    public FileSystem getFileSystem() {
        return fileSystem;
    }

    public void setFileSystem(FileSystem fileSystem) {
        this.fileSystem = fileSystem;
    }


    public static void main(String[] args) throws IOException {
        HdfsFileService hdfsFileService = new HdfsFileService();
        FileSystem fileSystem = FileSystem.get(new Configuration());
        hdfsFileService.setFileSystem(fileSystem);
        hdfsFileService.upload("sdsdsds","/document/xmlfile_1513655472574_14.bigfile");


    }
}